package BuiltinProtocol

import (
	"encoding/binary"
	"io"

	. "git.oschina.net/yangdao/SGNet2"
	. "git.oschina.net/yangdao/extlib/data_type"
	"github.com/golang/protobuf/proto"
)

type PBSizeAndId struct {
	HeadBuf    []byte
	DataEvents *TypVector
}

func NewPBSizeAndId() IProtocl {
	return &PBSizeAndId{
		HeadBuf:    make([]byte, 4),
		DataEvents: Vector(),
	}
}

func (this *PBSizeAndId) Receive(rw io.ReadWriter) (interface{}, error) {
	_, err := io.ReadFull(rw, this.HeadBuf)
	if err != nil {
		return nil, err
	}
	size := binary.BigEndian.Uint32(this.HeadBuf)
	data := make([]byte, size)

	_, err = io.ReadFull(rw, data)
	if err != nil {
		return nil, err
	}

	return data, nil
}

func (this *PBSizeAndId) Close() error {
	return nil
}

func (this *PBSizeAndId) Send(data ...interface{}) (interface{}, error) {
	bydata, err := proto.Marshal(data[1].(proto.Message))
	if err != nil {
		return nil, err
	}
	SendData := make([]byte, len(bydata)+6)
	binary.BigEndian.PutUint32(SendData, uint32(len(bydata)+2))
	binary.BigEndian.PutUint16(SendData[4:], uint16(data[0].(int)))
	copy(SendData[6:], bydata)
	//sess.Out <- SendData
	return SendData, nil
}

func (this *PBSizeAndId) DispatchPacket(sess *Session, data interface{}) {
	byData := data.([]byte)
	msgId := binary.BigEndian.Uint16(byData[:2])
	for i := 0; i < this.DataEvents.Count(); i++ {

		this.DataEvents.Nth(i).(func(*Session, uint16, []byte))(sess, msgId, byData[2:])
	}
}

func (this *PBSizeAndId) AddPacketEvent(fn interface{}) {
	this.DataEvents.Conj(fn)
}
